原始题目:剑指 Offer 09. 用两个栈实现队列 (opens new window)

解题思路:

使用两个栈,可以实现一个队列。

假设有两个栈,一个栈是 S1S1,一个是 S2S2

入队操作

直接向 S1S1 压入数据。

出队操作

因为队列是先进先出,如果直接从 S1S1 弹出数据显然不对,我们要的是 S1S1 最底下的元素。

因此我们先把 S1S1 的元素全部弹出并压入 S2S2,这样 S2S2 的栈顶就是要出队的元素。只要 S2S2 不为空,那么它的栈顶就应该是要出队的数据。

出队时,先判断 S2S2 是否为空,不为空则弹出栈顶。如果为空,则回到原始状态,将 S1S1 的元素压入 S2S2

需要注意的是,一定要 S2S2 为空的时候,才能把 S1S1 的数据弹出并压入到 S2S2

代码:

class CQueue {
    Deque<Integer> s1 = new LinkedList<>();
    Deque<Integer> s2 = new LinkedList<>();

    public CQueue() {

    }

    public void appendTail(int value) {
        s1.push(value);
    }

    public int deleteHead() {
        if(!s2.isEmpty()){
            return s2.pop();
        }
        while(!s1.isEmpty()){
            s2.push(s1.poll());
        }
        return s2.isEmpty() ? -1 : s2.pop();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

复杂度分析

  • 时间复杂度appendTail 函数为 O(1)O(1)deleteHeadNN 次删除队首元素后,需要进行 NN 个元素的倒序,为O(N)O(N)

  • 空间复杂度O(N)O(N):最差的情况下,S1S1S2S2 共保存 NN 个元素。

上次更新: 2023/10/15